use std::path::Path;
use std::fs::File;
use std::io::BufReader;
use serde::{Serialize, Deserialize};
use std::io::BufWriter;
use std::thread;
use libloader::libloading;
use walkdir::DirEntry;
use walkdir::WalkDir;
use libloader::get_libfn;
use std::collections::HashMap;
use thread_priority::*;
#[derive(Serialize, Deserialize, Debug,Clone)]
struct cache {
    owner:String,
    token:String,
    basepath:String
}
fn rustinput(a:&str)->String{
    println!("{}",a);
    let mut tmp = String::new();
    std::io::stdin().read_line(&mut tmp).expect("read_line error!");
    return tmp.trim().to_string();
}
fn main() {
    let backhandle = thread::spawn(|| {
        get_libfn!("backenddll.dll", "filedirfunc",filedirfunc ,(),basepath:String,owner:String,repo:String,token:String);
        filedirfunc
    });
    set_current_thread_priority(ThreadPriority::Max);
    let mut cachepath = rustinput("input cachefile");
    let cachePath = Path::new(&cachepath);
    let mut config:cache;
    if cachePath.exists(){
        let file = File::open(&cachepath).unwrap();
        let reader = BufReader::new(file);
        config = serde_json::from_reader(reader).unwrap();
    }else{
        let mut owner = rustinput("input owner");
        let mut token = rustinput("input token");
        let mut basepath = rustinput("input basepath");
        let mut sizemaxg = rustinput("input sizemax(gb)").parse::<f64>().unwrap();
        let sizemax:u64 = (sizemaxg*1024.0*1024.0*1024.0) as u64;
        config = cache{
            owner:owner,
            token:token,
            basepath:basepath,
        };
        println!("Cachepath: {}", cachepath);
        let file = File::create(&cachepath).unwrap();
        let writer = BufWriter::new(file);
        serde_json::to_writer(writer, &config).unwrap();
    }
    let mut inputnum:u16 = 0;
    let filedirfunc=backhandle.join().unwrap();
    let mut paths = HashMap::new();
    loop{
        let inputstr = format!("input repo,now input {} path",inputnum);
        let mut repo = rustinput(&inputstr);
        if repo==""{
            println!("error");
            continue;
        }
        let mut fullstr:String =config.basepath.clone()+&repo+r"\";
        let fullstrPath = Path::new(&fullstr);
        let owner_clone = config.owner.clone();
        let token_clone = config.token.clone();
        if paths.contains_key(&fullstr){
            println!("error");
            continue;
        }
        if fullstrPath.exists(){
            paths.insert(fullstr.clone(),1);
            thread::spawn(move ||{
                filedirfunc(fullstr,owner_clone,repo.into(),token_clone);
            });
            inputnum+=1;
            continue;
        }else{
            println!("error");
            continue;
        };
    }
}
